﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace PlayBox
{
    public partial class Download : Form
    {
        private BackgroundWorker _worker;
        private String id;
        private String filename;

        public DataClasses.Music music { get; set; }

        private long totalSize;
        private long received;
        private int progress = -1;

        public Download()
        {
            InitializeComponent();

            _worker = new BackgroundWorker();
            _worker.WorkerReportsProgress = true;
            _worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
            _worker.ProgressChanged += new ProgressChangedEventHandler(_worker_ProgressChanged);
            _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
            _worker.WorkerSupportsCancellation = true;


            this.FormClosing += new FormClosingEventHandler(Download_FormClosing);
        }

        void Download_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_worker.IsBusy)
                _worker.CancelAsync();
        }

        void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.Close();
        }

        void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progress = e.ProgressPercentage;

            // Keine Ahnung?
            if (progress == -1 && progressBar.Style != ProgressBarStyle.Marquee)
                progressBar.Style = ProgressBarStyle.Marquee;
            else
            {
                // Fortschritt
                if (progressBar.Style != ProgressBarStyle.Continuous)
                    progressBar.Style = ProgressBarStyle.Continuous;

                progressBar.Value = progress;
            }
            

            lblTotal.Text = totalSize.ToString("#,0");
            lblReceived.Text = received.ToString("#,0");
        }

        /// <summary>
        /// Herunterladen
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _worker_DoWork(object sender, DoWorkEventArgs e)
        {
            // Stream holen
            System.IO.Stream stream = null;
            try
            {
                var downloadInfo = ServerConnection.Current.DownloadItem(id);

                // Daten setzen
                stream = downloadInfo.ContentStream;
                totalSize = downloadInfo.ContentLength;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Download fehlgeschlagen.\n" + ex.Message, "Fehler", MessageBoxButtons.OK);
                return;
            }

            // Anfangsstatus setzen
            received = 0;

            _worker.ReportProgress(0);

            // Buffer initialisieren
            int BUFFERSIZE = 256000;
            int offset = 0;
            byte[] buffer = new byte[BUFFERSIZE];

            int lastUpdate = DateTime.Now.Second;

            

            // ---------------------
            // Lesen
            // ---------------------

            // Memory Stream zum Zwischenspeichern
            System.IO.MemoryStream memstream = null;

            // Enc
            EncryptionLayer enc = null;

            try
            {
                memstream = new System.IO.MemoryStream();

                int read;
                while ((read = stream.Read(buffer, offset, BUFFERSIZE)) != 0)
                {
                    received += read;

                    // Cancel?
                    if (e.Cancel)
                    {
                        // Memory Stream wird nachher aufgelöst
                        break;
                    }

                    // Jede Sekunde updaten
                    if (lastUpdate != DateTime.Now.Second)
                    {
                        lastUpdate = DateTime.Now.Second;
                        _worker.ReportProgress(totalSize == -1 ? -1 : (int)((float)received / (float)totalSize * 100));
                    }

                    memstream.Write(buffer, offset, read);
                }

                _worker.ReportProgress(100);

                // Verschlüsselt speichern
                if (!e.Cancel)
                {
                    string targetPath = User.UserData.GetDirectoryPath("Data\\" + filename );
                    if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(targetPath)))
                        System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(targetPath));
                    
                    music.SongStream = memstream;
                    music.SaveToDisk();
                }
            }
            catch
            {

            }
            finally
            {
                if (stream != null)
                    stream.Close();

                if (memstream != null)
                    memstream.Close();

                if (enc != null)
                    enc.close();
            }

            
        }

        /// <summary>
        /// Startet den Download einer bestimmten ID
        /// </summary>
        /// <param name="id">ID des Objekts zum Downloaden</param>
        /// <param name="filename">Dateiname, wo gespeichert wird</param>
        public void StartDownload (String id, String filename)
        {
            this.id = id;
            this.filename = filename;

            _worker.RunWorkerAsync();

            this.ShowDialog();
        }
    }
}
